<?php

namespace App\Services\Accompany;

use App\Enums\AccompanyEnum;
use App\Exceptions\BasicException;
use App\Models\MainDB\Accompany\AccompanyAbility;
use App\Models\MainDB\Accompany\AccompanyCouponUser;
use App\Models\MainDB\Accompany\AccompanyGame;
use App\Models\MainDB\Accompany\AccompanyLabel;
use App\Repositories\Accompany\AccompanyAbilityRepository;
use App\Repositories\Accompany\AccompanyOrderRepository;
use App\Repositories\Accompany\AccompanyUserAdvantageLabelRepository;

class AccompanyAbilityService
{

    /**
     * 我的技能列表
     * @param $userId
     * @param $type
     * @return array
     */
    public function getList($userId,$type): array
    {
        $abilitys = AccompanyAbilityRepository::getInstance()->getList($userId, $type);
        $couponUser = AccompanyCouponUser::query()->where(['type' => 1, 'status' => 0, 'user_id' => UID])->first();
        $data = [];
        foreach ($abilitys as $ability) {
            $price = $ability['price'];
            $reducedPrice = 0;
            $isReduce = 0;
            if ($userId != UID && $couponUser && $ability['type'] == AccompanyEnum::ACCOMPANY_TYPE_GAME) {
                $isReduce = 1;
                $reducedPrice = $ability['price'];
                $price = $couponUser->reduce >= $price ? 0 : bcsub($price, $couponUser->reduce, 2);
            }
            $data[] = [
                'id'            => $ability['id'],
                'game_id'       => $ability['game_id'],
                'game_level'    => $ability['game_level'],
                'game_service'  => $ability['game_service'],
                'game_name'     => $ability['game_name'],
                'open'          => $ability['open'],
                'introduction'  => $ability['introduction'],
                'label'         => explode(',', $ability['label']),
                'picture'       => $ability['picture'],
                'can_order'     => $ability['price'] == 0 ? 0 : 1,
                'price'         => (int)$price,
                'is_reduce'     => $isReduce,
                'reduced_price' => $reducedPrice,
                'game_picture'  => $ability['accompany_game']['picture'] ?? '',
                'order_count'   => $ability['order_count'],
                'grade'         => $ability['grade'],
                'sounds'        => $ability['sounds'],
                'sounds_time'   => $ability['sounds_time'],
                'status'        => $ability['status'],
                'unit'          => $ability['unit'],
                'type'          => $ability['type'],
                'unit_quantity' => $ability['unit_quantity'],
                'unit_desc' => $ability['unit_desc'],
            ];
        }
        return $data;
    }

    /**
     * 技能详情
     *
     * @param $userId
     * @param $abilityId
     *
     * @return array
     * @throws BasicException
     */
    public function getDetail($userId, $abilityId): array
    {
        $ability = AccompanyAbility::query()
            ->with(['user', 'user_data', 'accompany_game'])
            ->where(['id' => $abilityId, 'user_id' => $userId])
            ->first();
        if (empty($ability)) {
            throw new BasicException(-1, '技能不存在');
        }
        $labelId         = AccompanyUserAdvantageLabelRepository::getInstance()->detail($ability['id'])->toArray();
        $labelId         = array_column($labelId, 'label_id');
        $res             = $this->buildAccompanyData($ability);
        $res['label_id'] = $labelId;
        return $res;
    }

    public function abilityInfo()
    {
        $game = AccompanyGame::query()->where('status', 1)
            ->where('type',AccompanyEnum::ACCOMPANY_TYPE_GAME)
            ->get();
        foreach ($game as &$value) {
            $value['level'] = explode(',', $value['level']);
            $value['service'] = explode(',', $value['service']);
            $value['price'] = explode(',', $value['price']);
            $label = AccompanyLabel::query()->whereRaw("FIND_IN_SET(?,game_id)", [$value['id']])->get()->toArray();
            $value['label'] = array_column($label, 'name');

        }
        return $game;

    }

    /**
     * @throws BasicException
     */
    public function savaAbility($data): bool
    {
        $game = AccompanyGame::query()->where('id', $data['game_id'])->first();

        $count = AccompanyAbility::query()->where('user_id',$data['user_id'])
            ->where('game_id',$data['game_id'])
            ->whereIn('status',[0,1])
            ->count();
        if ($count >0){
            throw new BasicException(-1, "该游戏提交认证");
        }
        $price = explode(',', $game['price']);
        if ($data['price'] != 0 && !in_array($data['price'], $price)) {
            throw new BasicException(-1, "价格不在范围内");
        }
        $list = [
            'game_level'   => $data['game_level'],
            'game_service' => $data['game_service'],
            'label'        => implode(',', $data['label']),
            'picture'      => $data['picture'],
            'sounds'       => $data['sounds'],
            'sounds_time'  => $data['sounds_time'],
            'introduction' => $data['introduction'],
            'unit'         => $game['unit'],
        ];
        $res = [
            'user_id'   => $data['user_id'],
            'game_id'   => $data['game_id'],
            'game_name' => $data['game_name'],
            'price'     => $data['price'],
            'grade'     => '5.0',
            'status'    => 0,
            'open'      => 0,
            'unit'         => $game['unit'],
            'content'   => json_encode($list, true),
        ];


        $id = AccompanyAbilityRepository::getInstance()->create($res);
        if (!empty($data['label_id'])) {
            $label = explode(',', $data['label_id']);
            foreach ($label as $value) {
                AccompanyUserAdvantageLabelRepository::getInstance()->blind($data['user_id'], $value,$id);
            }
        }
        return true;
    }

    /**
     * 获取用户的评分和接单次数
     * @param $userId
     * @param $abilityId
     * @return array
     */
    public function getUserGradeAndCount($userId, $abilityId): array
    {
        $orderCount = 0;
        $orderScore = 0;
        $orderArr = AccompanyOrderRepository::getInstance()->getOrderByUserId($userId, $abilityId);
        if (!empty($orderArr)) {
            $orderCount = count($orderArr);
            $orderScore = array_sum(array_column($orderArr, 'grade')) / $orderCount;
        }
        return [
            $orderCount,
            $orderScore,
        ];
    }

    public function editPrice($data): bool
    {
        $ability = AccompanyAbility::query()->where('id', $data['id'])->first();
        $game = AccompanyGame::query()->where('id',$ability['game_id'])->first();
        $list = [
            'price' => $data['price'],
            'unit'  => $game['unit']
        ];

        AccompanyAbility::query()->where('id', $data['id'])->update($list);
        return true;

    }

    /**
     * @throws BasicException
     */
    public function editAbility($data): bool
    {
        $ability = AccompanyAbilityRepository::getInstance()->detail($data);
        $game = AccompanyGame::query()->where('id', $ability['game_id'])->first();
        $res = [
            'game_level'   => $data['game_level'],
            'game_service' => $data['game_service'],
            'label'        => implode(',', $data['label']),
            'picture'      => $data['picture'],
            'sounds'       => $data['sounds'],
            'sounds_time'  => $data['sounds_time'],
            'introduction' => $data['introduction'],
        ];
        $list = [
            'game_name'    => $game['name'],
            'content' => json_encode($res, true),
        ];
        if ($ability['status'] == 0 || !empty($ability['content'])) {
            throw new BasicException(-1, "审批中");
        }
        if ($ability['status'] == 2) {
            $list['status'] = 0;
        }
        AccompanyAbility::query()->where('id', $data['id'])->update($list);

        if (!empty($data['label_id'])) {
            AccompanyUserAdvantageLabelRepository::getInstance()->delBlind($data['user_id'], $data['id']);
            $label = explode(',', $data['label_id']);
            foreach ($label as $value) {
                AccompanyUserAdvantageLabelRepository::getInstance()->blind($data['user_id'], $value,$data['id']);
            }
        }

        return true;

    }

    public function buildAccompanyData($ability, $origin = 'self'): array
    {
        $gameLevel = $ability['game_level'];
        $gameService = $ability['game_service'];
        $label = $ability['label'];
        $picture = $ability['picture'];
        $sounds = $ability['sounds'];
        $soundsTime = $ability['sounds_time'];
        $introduction = $ability['introduction'];
        $content = $ability['content'];
        $price = $ability['price'];
        $reducedPrice = 0;
        $isReduce = 0;
        $userId = $ability['user_id'];
        if ($origin == 'self') {
            if (!empty($data['content']) && $ability['status'] == 1) {
                $content = json_decode($data['content'], true);
                $gameLevel = $content['game_level'];
                $gameService = $content['game_service'];
                $label = $content['label'];
                $picture = $content['picture'];
                $sounds = $content['sounds'];
                $soundsTime = $content['sounds_time'];
                $introduction = $content['introduction'];
                $content = '';
            }
        }
        $couponUser = AccompanyCouponUser::query()->where(['type' => 1, 'status' => 0, 'user_id' => UID])->first();
        if ($couponUser && $origin == 'accompany') {
            $isReduce = 1;
            $reducedPrice = $ability['price'];
            $price = $couponUser->reduce >= $price ? 0 : bcsub($price, $couponUser->reduce, 2);
        }
        //$labelId =AccompanyUserAdvantageLabelRepository::getInstance()->detail($ability['id'])->toArray();
        //$labelId = array_column($labelId,'label_id');
        return [
            'id'            => $ability['id'],
            'game_id'       => $ability['game_id'],
            'user_id'       => $userId,
            'nickname'      => $ability['user_data']['nickname'],
            'head_picture'  => $ability['user_data']['head_picture'],
            'sex'           => $ability['user_data']['sex'],
            'age'           => isset($ability['user_data']['birthday']) ? birthToAge($ability['user_data']['birthday'], true) : 0,
            'game_level'    => $gameLevel,
            'game_service'  => $gameService,
            'game_name'     => $ability['accompany_game']['name'],
            'open'          => $ability['open'],
            'introduction'  => $introduction,
            'label'         => explode(',', $label),
            'picture'       => $picture,
            'price'         => str_replace('.00', '', $price),
            'is_reduce'     => $isReduce,
            'reduced_price' => str_replace('.00', '', $reducedPrice),
            'game_picture'  => $ability['accompany_game']['picture'] ?? '',
            'order_count'   => $ability['order_count'],
            'grade'         => $ability['grade'],
            'sounds'        => $sounds,
            'sounds_time'   => $soundsTime,
            'status'        => $ability['status'],
            'unit'          => $ability['accompany_game']['unit'],
            'content'       => $content,
            'type'          => $ability['type'],
            //'label_id'      => $labelId
        ];
    }

    public function applyInfo($userId): array
    {
        $data['user_id'] = $userId;
        $resData['apply_status'] = 0; //未申请
        $data = AccompanyAbilityRepository::getInstance()->applyInfo($userId);
        foreach ($data as $value) {
            if ($value['status'] == 1) {
                $resData['apply_status'] = 1; //认证成功
                break;
            }
            if ($value['status'] == 2) {
                $resData['apply_status'] = 2;
            }
        }
        return $resData;

    }

    /**
     * 更新技能开关
     * @param $userId
     * @param $abilityId
     * @param $isOpen
     * @return int
     */
    public function updateOpen($userId, $abilityId, $isOpen): int
    {
        return AccompanyAbility::query()
            ->where(['id' => $abilityId, 'user_id' => $userId])->update([
                'open' => $isOpen,
            ]);
    }
}
